package com.asen.commons.core.concurrent;

//import com.asen.commons.core.util.LoginUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Collection;
import java.util.concurrent.*;

/**
 * 线程池
 *
 * @author Gary
 * @version 1.0
 * @date 2019-10-19
 */
@Slf4j
@Component
// TODO
public class GenericThreadPool {

    @Value("${scp.threadPool.coreSize:3}")
    private int coreSize;

    @Value("${scp.threadPool.maxSize:1000}")
    private int maxSize;

    @Value("${scp.threadPool.keepAlive:5000}")
    private long keepAlive;

    private ThreadPoolExecutor threadPool;

    @PostConstruct
    public void init() {
        threadPool = new ThreadPoolExecutor(coreSize, maxSize, keepAlive, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(), new GenericThreadFactory(null), new RejectedExecutionHandler() {

            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                log.warn("线程池超过最大线程数{}，以当前线程执行！", maxSize);
                if (!executor.isShutdown()) {
                    r.run();
                }
            }
        });
    }

    //public void execute(RunnableTask task) {
    //    execute(task, false);
    //}

    //public void executeQuietly(RunnableTask task) {
    //    execute(task, true);
    //}

    //public void execute(RunnableTask task, boolean quietly) {
    //    String token = LoginUtils.getTokenQuietly();
    //    Long tenantId = LoginUtils.getTenantIdQuietly();
    //    threadPool.execute(() -> {
    //        try {
    //            ThreadLocalCache.setAuthToken(token);
    //            ThreadLocalCache.setTenantId(tenantId);
    //            task.execute();
    //        } catch (Exception e) {
    //            log.error("执行失败！", e);
    //            if (!quietly) {
    //                throw new RuntimeException(e);
    //            }
    //        } finally {
    //            ThreadLocalCache.clear();
    //        }
    //    });
    //}

    //public <V> Future<V> submit(CallableTask<V> task) {
    //    String token = LoginUtils.getTokenQuietly();
    //    Long tenantId = LoginUtils.getTenantIdQuietly();
    //    Future<V> future = threadPool.submit(() -> {
    //        V result = null;
    //        try {
    //            ThreadLocalCache.setAuthToken(token);
    //            ThreadLocalCache.setTenantId(tenantId);
    //            result = task.call();
    //        } catch (Exception e) {
    //            log.error("执行失败！", e);
    //            throw new RuntimeException(e);
    //        } finally {
    //            ThreadLocalCache.clear();
    //        }
    //        return result;
    //    });
    //    return future;
    //}

    /**
     * 多线程批量执行（线程执行出时，中断并抛异常）
     *
     * @param collection
     * @throws Exception
     */
    //public void batchExecute(Collection<? extends RunnableTask> collection) throws Exception {
    //    batchExecute(collection, true);
    //}

    /**
     * 多线程批量执行（线程执行出错时，不中断不抛异常）
     *
     * @param collection
     * @throws Exception
     */
    //public void batchExecuteQuietly(Collection<? extends RunnableTask> collection) throws Exception {
    //    batchExecute(collection, false);
    //}

    /**
     * 多线程批量执行
     *
     * @param collection
     * @param throwException
     * @throws Exception
     */
    //public void batchExecute(Collection<? extends RunnableTask> collection, boolean throwException) throws Exception {
    //    if (collection == null || collection.isEmpty()) {
    //        return;
    //    }
    //
    //    String token = LoginUtils.getTokenQuietly();
    //    Long tenantId = LoginUtils.getTenantIdQuietly();
    //    CountDownLatch latch = new CountDownLatch(collection.size());
    //    for (RunnableTask runnable : collection) {
    //        threadPool.execute(() -> {
    //            try {
    //                ThreadLocalCache.setAuthToken(token);
    //                ThreadLocalCache.setTenantId(tenantId);
    //                runnable.execute();
    //            } catch (Exception e) {
    //                log.error("执行失败！", e);
    //                if (throwException) {
    //                    throw new RuntimeException(e);
    //                }
    //            } finally {
    //                latch.countDown();
    //                ThreadLocalCache.clear();
    //            }
    //        });
    //    }
    //
    //    latch.await();
    //}

    //public BatchExecuteBuilder builder() {
    //    return new BatchExecuteBuilder(this);
    //}

    @PreDestroy
    public void destroy() {
        threadPool.shutdown();
    }
}
